package com.harboursoftware.xstorage.integration

import junit.framework.Assert;

import org.jets3t.service.acl.AccessControlList; 
import org.jets3t.service.acl.CanonicalGrantee 
import org.jets3t.service.acl.GroupGrantee 
import org.jets3t.service.acl.Permission;
import org.jets3t.service.Jets3tProperties 
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.security.AWSCredentials 
import org.junit.After 
import org.junit.Before 
import org.junit.Test 

import com.harboursoftware.xstorage.TestDatabaseProvider 
import com.harboursoftware.xstorage.db.sql.UserSqlDao 
import com.harboursoftware.xstorage.model.XUser 

/**
* integration test for operations on bucket.
* <p>
* before running tests,please start Hadoop server and change <a href="C:\windows\system32\drivers\etc\hosts">hosts file</a> first.
* <p/>
* <p>configuration file : src/test/resources/xstorage.config.</p>
* <b>supported by <a href="http://jets3t.s3.amazonaws.com/index.html">Jets3t</a></b>
*
* @since 0.1
* @author Simon Leung
*/
class BucketOperationsTest { 
    def awsAccessKey = '0PN5J17HBGZHT7JJ3X82'
    def awsSecretAccessKey = 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o'
    def email = 'testuser@harboursoftware.com'
    def bucketName = 'harboursoftware'
    def s3Service 
    
    @Before
    void setUp() {
        Jets3tProperties props = new Jets3tProperties();
        props.setProperty("s3service.https-only", 'false')
        props.setProperty('s3service.internal-error-retry-max', '0')
        AWSCredentials credentials = new AWSCredentials(awsAccessKey, awsSecretAccessKey);
        s3Service = new RestS3Service(credentials, 'x-storage-test', null, props);
        
        //准备user数据
        def databaseProvider = new TestDatabaseProvider()
        databaseProvider.recreateDatabase()
        def userDao = new UserSqlDao(databaseProvider)
        def user = new XUser(null, awsAccessKey, awsSecretAccessKey, email, email)
        userDao.saveUser user
    }
    
    @After
    void tearDown() {
        s3Service = null
    }
    /**
    * test <a href="http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html">Put Bucket</a>, <a
    * href="http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGET.html">Get Bucket</a>
    */
   @Test
   void test_put_get_delete_bucket() {
       
       s3Service.createBucket(bucketName)
       
       def bucket = s3Service.getBucket(bucketName)
       
       assert bucket.name == bucketName
       
       s3Service.deleteBucket bucketName
       
       bucket = s3Service.getBucket(bucketName)
       assert bucket == null
   }


   @Test
   void test_put_get_bucket_acl() {
       s3Service.createBucket(bucketName)
       
       def oldAcl = s3Service.getBucketAcl(bucketName)
       
       def newAcl = new AccessControlList()
       newAcl.owner = oldAcl.owner
       
       def owner = new CanonicalGrantee(oldAcl.owner.id)
       owner.displayName = oldAcl.owner.displayName
       newAcl.grantPermission owner, Permission.PERMISSION_FULL_CONTROL
       
       def allUser = GroupGrantee.ALL_USERS 
       newAcl.grantPermission allUser, Permission.PERMISSION_READ
               
       s3Service.putBucketAcl(bucketName, newAcl)
       
       def persistedAcl = s3Service.getBucketAcl(bucketName)

       assert persistedAcl.owner.id == newAcl.owner.id
       assert persistedAcl.grants.size() == 2
       def counter = 0
       persistedAcl.grants.each {
           def grantee = it.grantee
           def permission = it.permission
           if(grantee instanceof CanonicalGrantee) {
               counter++
               assert grantee.identifier == owner.id
               assert permission == Permission.PERMISSION_FULL_CONTROL
           } else if(grantee instanceof GroupGrantee) {
               counter++
               assert grantee == GroupGrantee.ALL_USERS
               assert permission == Permission.PERMISSION_READ
           }
       }
       assert counter == 2
       s3Service.deleteBucket bucketName 
   }

   void test_put_bucket_when_bucket_already_exists() {

   }

   void test_get_bucket_when_bucket_does_not_exists() {

   }

   void test_put_bucket_acl_when_bucket_does_not_exists() {

   }

   void test_put_bucket_when_buckets_is_too_many() {

   }

   void test_put_bucket_when_bucket_name_is_invaild() {

   }
}
